<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/5/22
 * Time: 16:19
 */

//定义核心类
namespace Shop; //定义命名空间

//判断常量是否存在
use Controller\IndexController;
use Model\IndexModel;

if(!defined("SHOP")){
    header('Location:../index.php');
    exit;
}

class Application {
    //入口
    public static function Run(){
        //1.字符集
        self::setCharset();
        //2. 设置目录常量
        self::setDir();
        //3. 加载配置
        self::setConfig();
        //4. 设置错误
        self::setError();
        //        加载smarty
        self::setSmarty();
        //5. 自动加类
        self::setSpl();
        //6.url 拆分 实例化对应的类调用对应的方法
        self::setUrl();

    }

    static private function setSmarty(){
        include SHOP_EXTEND.'/smarty/Smarty.class.php';
    }

    //设置字符集
    private static function setCharset(){
        header("Content-type:text/html;charset=utf8");
    }

    //设置目录常量
    private static function setDir(){
        $dir=str_replace("\\",'/',str_replace('Core','',__DIR__)); //得到网站根目录
        define("SHOP_DIR",$dir);//网站根目录
        define("SHOP_CORE",$dir.'Core/');//核心目录
        define("SHOP_PUBLIC",$dir.'Public/');//资源目录
        define("SHOP_CONFIG",$dir.'Config/');//配置目录
        define("SHOP_EXTEND",$dir.'Extend/');//插件目录
        //MVC
        define("SHOP_CONTROLLER",$dir.'Application/'.SHOP.'/Controller/');//控制器文件目录
        define("SHOP_MODEL",$dir.'Application/'.SHOP.'/Model/');//模型文件目录
        define("SHOP_VIEW",$dir.'Application/'.SHOP.'/View/');//视图文件目录
    }

    //引入配置
    private static function setConfig(){
        $GLOBALS['Config'] = include SHOP_CONFIG.'config.php';
    }

    //设置错误
    private static function setError(){
        //设置错误信息

        //ini_set ： 修改PHP.ini 配置
        @ini_set('display_errors',$GLOBALS['Config']['display_errors']);
        @ini_set('error_reporting',$GLOBALS['Config']['error_reporting']);
    }


    //自动加载需要的类
    private static function setSpl(){
        //注册自动加载函数，自动加载函数在类里面使用需要数组形式的参数
        //self 当前类， autoCore 当前类下面的方法
        spl_autoload_register(array(self,'autoCore')); //核心类
        spl_autoload_register(array(self,'autoController')); //自动加载控制器
        spl_autoload_register(array(self,'autoExtend')); //自动加载第三方插件
        spl_autoload_register(array(self,'autoModel')); //自动加载模型

    }

    //自动加载第三方插件
    private static function autoExtend($a){
        //$a 携带了命名空间，但是对应的类文件文件名没有命名空间，所以需要去掉命名空间
//        $a=basename($a);//去掉命名空间
        //$a 要实例化的类名
        $a=SHOP_EXTEND.$a.'.php';
        if(is_file($a)){
            include $a;
        }
    }

    //自动加载核心类
    private static function autoCore($a){
        //$a 携带了命名空间，但是对应的类文件文件名没有命名空间，所以需要去掉命名空间
//        $a=str_replace("\\","/",$a);
        $a=basename($a);//去掉命名空间
        //$a 要实例化的类名
        $a=SHOP_CORE.$a.'.class.php';
        if(is_file($a)){
            include $a;
        }
    }
    //自动加载控制器
    private static function autoController($a){
        //$a 携带了命名空间，但是对应的类文件文件名没有命名空间，所以需要去掉命名空间
//        $a=str_replace("\\","/",$a);
        $a=basename($a);//去掉命名空间
        //$a 要实例化的类名
        $a=SHOP_CONTROLLER.$a.'.class.php';
        if(is_file($a)){
            include $a;
        }
    }
    private static function autoModel($a){
        //$a 携带了命名空间，但是对应的类文件文件名没有命名空间，所以需要去掉命名空间
//        $a=str_replace("\\","/",$a);
        $a=basename($a);//去掉命名空间
        //$a 要实例化的类名
        $a=SHOP_MODEL.$a.'.class.php';
        if(is_file($a)){
            include $a;
        }else{
            exit('类文件不存在');
        }
    }

    //接收 URL 参数，拆分得到 控制器 和方法
    private static function setUrl(){
        //C 代表控制器
        //F 代表方法
        //接收 参数
//        $_REQUEST 可以接收get 参数 也可以接收post参数
        $C= isset($_REQUEST['C'])?$_REQUEST['C']:'Index';
        $F= isset($_REQUEST['F'])?$_REQUEST['F']:'index';

        $C=$C.'Controller'; //得到对应的控制器类名
//        echo $C;exit;
        //定义常量保存起来，分别后面使用
        define('SHOP_C',$C);
        define('SHOP_F',$F);

        $C="\\Controller\\".$C; //加上命名空间

        // 实例化 对应的类名，调用对应的方法
        $obj=new $C();
        //判断是否有对应的方法
        if(method_exists($obj,$F)){
            $obj->$F();
        }else{
            exit('方法不存在');
        }

    }

}